#ifndef _MATRIX_H__
#define _MATRIX_H__

#include"Vector3.h"
#include"Vector4.h"
#include"Quaternion.h"

#include<LinearMath/btTransform.h>

class Matrix : public D3DXMATRIX
{
public:
	inline void SetPosition(Vector3 const &vec3) { m[3][0] = vec3.x; m[3][1] = vec3.y; m[3][2] = vec3.z; m[3][3] = 1.0f; }
	inline void SetPosition(Vector4 const &vec4) { m[3][0] = vec4.x; m[3][1] = vec4.y; m[3][2] = vec4.z; m[3][3] = vec4.w; }
	inline Vector3 GetPosition() const { return Vector3(m[3][0], m[3][1], m[3][2]); }
	inline Vector3 Transform(Vector3 &v) { Vector4 temp(v), out; D3DXVec4Transform(&out, &temp, this); return Vector3(out.x, out.y, out.z); }
	inline Vector4 Transform(Vector4 &v) { Vector4 temp; D3DXVec4Transform(&temp, &v, this); return temp; }
	inline Matrix Inverse() const { Matrix out; D3DXMatrixInverse(&out, NULL, this); return out; }

	inline void CreateTranslation(const Vector3 &pos) { this->SetToIdentity(); m[3][0] = pos.x; m[3][1] = pos.y; m[3][2] = pos.z; }
	inline void CreateTranslation(const float x, const float y, const float z) { this->SetToIdentity(); m[3][0] = x; m[3][1] = y; m[3][2] = z; }

	inline void ApplyRotationX(const float radians) { Matrix temp; D3DXMatrixRotationX(&temp, radians); *this *= temp; }
	inline void ApplyRotationY(const float radians) { Matrix temp; D3DXMatrixRotationY(&temp, radians); *this *= temp; }
	inline void ApplyRotationZ(const float radians) { Matrix temp; D3DXMatrixRotationZ(&temp, radians); *this *= temp; }

	inline void CreateRotationX(const float radians) { D3DXMatrixRotationX(this, radians); }
	inline void CreateRotationY(const float radians) { D3DXMatrixRotationY(this, radians); }
	inline void CreateRotationZ(const float radians) { D3DXMatrixRotationZ(this, radians); }

	inline void CreateFromYawPitchRoll(const float yaw, const float pitch, const float roll) { D3DXMatrixRotationYawPitchRoll(this, yaw, pitch, roll); }

	inline void CreateFromQuaternion(const D3DXQUATERNION &q) { D3DXMatrixRotationQuaternion(this, &q); }

	Matrix(D3DXMATRIX &mat) { memcpy(&m, &mat.m, sizeof(mat.m)); }
	Matrix() : D3DXMATRIX() {}

	inline Matrix operator=(const btTransform &b)
	{
		Matrix out;
		btScalar* tma;
		b.getOpenGLMatrix(tma);
		out = D3DXMATRIX(tma);
		return out;
	}

	inline btTransform ConvertToBulletTransform()
	{
		btTransform out;
		btScalar* mma;
		mma = (float*)this;
		out.setFromOpenGLMatrix(mma);
		return out;
	}

	inline Matrix operator * (const Matrix &b)
	{
		Matrix out;
		D3DXMatrixMultiply(&out, this, &b);
		return out;
	}

	inline void SetToIdentity()
	{
		*this = D3DXMATRIX(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);
	}
};

#endif